﻿// ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <vector>
#include <opencv2/opencv.hpp>
int main()
{
	int srcImageW = 400;
	int srcImageH = 400;
	int sjX = 0;
	int sjY = 0;
	int sjW = 400;
	int sjH = 400;
	int ch = 3;

	cv::Mat mat = cv::imread("D:\\Desktop\\2.bmp");

	unsigned char* srcImage = new unsigned char[srcImageW * srcImageH * 3];
	memcpy_s(srcImage, srcImageW * srcImageH * 3, mat.data, srcImageW * srcImageH * 3);

	std::unique_ptr<unsigned char> grayImage(new unsigned char[srcImageW * srcImageH]);

	// 转灰度

	for (int row = 0; row < srcImageH; row++)
	{
		for (int col = 0; col < srcImageW; col++)
		{
			int index = (row * srcImageW + col) * 3;
			grayImage.get()[row * srcImageW + col] = static_cast<unsigned char>(0.299 * srcImage[index + 2] + 0.587 * srcImage[index + 1] + 0.114 * srcImage[index]);
		}
	}


	// 二值化
	for (int row = 0; row < srcImageH; row++)
	{
		for (int col = 0; col < srcImageW; col++)
		{
			grayImage.get()[row * srcImageW + col] = grayImage.get()[row * srcImageW + col] > 30 ? 255 : 0;
		}
	}

	cv::Mat bimMat = cv::Mat(srcImageH, srcImageW, CV_8UC1, grayImage.get());


	cv::Mat blurredImage;
	cv::GaussianBlur(bimMat, blurredImage, cv::Size(3, 3), 0);

	cv::Mat edges;
	cv::Canny(blurredImage, edges, 50, 150);
	//cv::imshow("edges", edges);
	//cv::waitKey(0);

	std::vector<std::vector<cv::Point>> contours;
	cv::findContours(edges, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);

	std::vector<cv::Point> approx;
	try
	{

		cv::approxPolyDP(contours[1], approx, cv::arcLength(contours[1], true) * 0.02, true);


		// 当点x的坐标与其他点x坐标值相差小于5时，认为是同一点，删除

		for (int i = 0; i < approx.size(); i++)
		{
			for (int j = i + 1; j < approx.size(); j++)
			{
				if (abs(approx[i].x - approx[j].x) < 20)
				{
					approx.erase(approx.begin() + j);
					j--;
				}
			}
		}

		for (int i = 0; i < approx.size(); i++)
		{
			cv::circle(mat, approx[i], 3, cv::Scalar(0, 255, 0), -1);
		}
	}
	catch (const std::exception& ex)
	{
		std::cout << "AAAAAAAAAAAAAAAAAA——————————————————》：" << ex.what() << std::endl;
	}
	cv::imshow("edges", mat);
	cv::waitKey(0);

}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件，或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来，若要再次打开此项目，请转到“文件”>“打开”>“项目”并选择 .sln 文件
